package eol.vm;

/** The instructions and opcodes for our virtual machine. */
public interface InstructionSet {
    
    /** INVALID: An invalid opcode. Causes the machine to halt and catch on fire. */
    public final static byte INVALID = 0;
    
    /** RETURN: Return from the current invocation.
      * <p>If the invocation stack is nonempty, pops the invocation stack
      * and execution resumes with the popped invocation.
      * Otherwise the machine halts. */
    public final static byte RETURN = 1 ;
    
    /** FETCH v: fetch the value of a variable from the current environment.
     *  <p>v is a 24 bit operand which is an index into the constant table.
     *  <p>Pushes the value of the variable onto the stack.
     *  <p>Error if v is a not valid index into the constant table (or isn't a string).
     *  <p>Error if the variable is not the environment chain. */
    public final static byte FETCH = 2 ;
            
    /** STORE v: store a value in a variable from the current environment chain.
     *  <p>v is a 24 bit operand which is an index into the constant table.
     *  <p>The constant should be a stringValue that names a variable
     *  <p>Stores the top value from the stack in the environment
     *  in which the variable is declared.
     *  <p>Does not remove pop the stack!
     *  <p>Error if v is a not valid index into the constant table (or isn't a string).
     *  <p>Error if the variable is not the environment chain. */
    public final static byte STORE = 3 ;
    
	/** NEW_VAR v: store a value in a variable in the top environment.
	*  <p>v is a 24 bit operand which is an index into the constant table.
	*  <p>Stores the top value on the stack in the top environment
	*     of the environment chain.
	*     If the top environment does not already contain the variable,
	*     the variable is added to the top environment.
	*  <p>Does not pop the stack!
	*  <p>Error if v is a not valid index into the constant table (or isn't a string). */
	public final static byte NEW_VAR = 4 ;
	
	/** START_ENV : Push a fresh environment.
	 * <P> The current environment is next in the chain
	 */
	public final static byte START_ENV = 5 ;
	
	/** START_ENV : Pop the top environment off the environment chain.
	 */
	public final static byte END_ENV = 6 ;
            
    /** CONST i. Push a constant value
      * <p> i is a 24 bit operand which is an index into constants table.
      * <p>Pushes the values from the constants table 
      * <p>Error if i is not a valid index into the constant table. */
    public final static byte CONST = 7 ;
    
    	/** POP. Pop one item off the stack.  */	
    public final static byte POP = 8 ;
            
    /** BRANCH addr: Branch to a given address.
      * <p>addr is a 24 bit operand, which should be a code address
      * <p>Sets the pc to the address. */
    public final static byte BRANCH = 10;
            
    /** BRANCH_ON_NIL addr: Branch if the top stack value is Nil.
      * <p>addr is a 24 bit operand, which should be a code address.
      * <p>Pops the stack; branches to addr if the popped value is Nil */
    public final static byte BRANCH_ON_NIL = 11;
            
    /** CALL n: invoke a function with n arguments.
      * <p> Expects the stack to contain (from top down)
      * <ul><li>The arguments (last on top)
      *     <li>The closure (paraList, segNum', env') to be called. </ul>
      * <p>
      * This instruction first, makes a new environment mapping the parameters to the arguments;
      * this environment uses the environment env' captured in the closure as its
      * next environment. It then pushes the current invocation (segNum, pc, env),
      * sets pc to 0, and sets segment number to segNum'.
      * <p> Error if the stack is not as expected.
      * <p> Error if the number of arguments, n, does not match the number of
      *     parameters. */
    public final static byte CALL = 12 ;
            
    /** MAKE_CLOSURE s: Push a closure value representing a function.
     * <p>1 24 bit operand representing the segment number
     *    for the function's machine code.
     * <p>Expects the stack to contain (from top down)
     * <ul><li>The number of parameters
     *     <li>The parameter names as StringValue objects (last on top) </ul>
     * <p> This instruction makes a function value (or closure) consisting
     *     of a list of parameter names, the segment number that indicates.
     *     the function's machine code, and the current environment. 
     *     On a call the current environment will be the parent environment.
     * <p> Error if the stack is not as expected.
     */
    public final static byte MAKE_CLOSURE = 13 ;
    
    /** ADD Pop 2 values (y and x) off the stack and 
	 * push x + y.
	 * Error if either value is not a number.
     */
    public final static byte ADD = 20 ;

    /** SUBTRACT Pop 2 values (y and x) off the stack and 
	 * push x - y.
	 * Error if either value is not a number.
     */
    public final static byte SUBTRACT = 21 ;
    
    /** MULTIPLY Pop 2 values (y and x) off the stack and 
	 * push x * y.
	 * Error if either value is not a number.
     */
    public final static byte MULTIPLY = 22 ;

    /** MULTIPLY Pop 2 values (y and x) off the stack and 
	 * push x multiplied by y.
	 * Error if either value is not a number or if y is zero.
     */
    public final static byte DIVIDE = 23 ;
    
    /** EQUAL Pop 2 values (y and x) off the stack and either
     * push "true" if they are equal, or push Nil if they are not equal
     */
    public final static byte EQUAL = 30;
             
    /** NULL: Pop a value off the stack and either
     * push "true" if it is the Nil value,
     * or Nil if it is not Nil.
     */
    public final static byte NULL = 40 ;
    
    /** ATOMIC: Pop a value off the stack and either
     * push "true" if it is anything but a cons cell,
     * or Nil if it is a cons cell.
     */
    public final static byte ATOMIC = 41 ;
            
    /** CONS: Pop two values off the stack and push the resulting cons cell.
     */
    public final static byte CONS = 42 ;
            
    /** HEAD: Pop a cons cell off the stack and push its head.
     * Error if x is not a ConsValue. */
    public final static byte HEAD = 43 ;
    
    /** TAIL: Pop a cons cell off the stack and push its tail.
     * Error if x is not a ConsValue. */
    public final static byte TAIL = 44 ;
            
   /**  PRINT: Pop one value off the stack and print a string representation of it. */
    public final static byte PRINT  = 50; 
}
